/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package baseDatos;

import entidades.Animal;
import entidades.Bateria;
import entidades.Camara;
import entidades.Jaula;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import oracle.sql.DATE;

/**
 *
 * @author Facundo
 */
public class AnimalDAO {

    private String query;
    private Connection conDB;
    private PreparedStatement pst;

    public AnimalDAO(Connection con) {
        this.conDB = con;
    }

    //  public AnimalDAO(String nombre) {
    //     super(nombre);
    //}
    public AnimalDAO() {
    }

    /**
     * @return the query
     */
    public String getQuery() {
        return query;
    }

    /**
     * @param query the query to set
     */
    public void setQuery(String query) {
        this.query = query;
    }

    /**
     * @return the conDB
     */
    public Connection getConDB() {
        return conDB;
    }

    /**
     * @param conDB the conDB to set
     */
    public void setConDB(Connection conDB) {
        this.conDB = conDB;
    }

    /**
     * @return the pst
     */
    public PreparedStatement getPst() {
        return pst;
    }

    /**
     * @param pst the pst to set
     */
    public void setPst(PreparedStatement pst) {
        this.pst = pst;
    }

    /*
     * Metodo para insertar un animal recien nacido.
     * Recibe por parametro, un animal.
     * El animal se inserta en la base con los siguientes datos:
     * codigo_animal
     * nombre
     * madre
     * padre
     * ubicacion (codigo de jaula)
     * fecha de nacimiento
     * fecha de destete aproximada
     * fecha de ralgro aproximada
     */
    public boolean put(Animal ani) {
        boolean ret = false;
        Animal aux = null;
        try {
            /*
             * debemos verificar que ese animal no exista en la base, utilizamos su nombre y su fecha de
             * nacimiento
             */
            aux = this.getAnimal(ani.getNombre(), ani.getFecha_nacimiento());
            if (aux == null) {
                /*
                 * buscamos el codigo el codigo de la madre y del padre
                 */
                int codigoMadre = new AnimalDAO(this.getConDB()).getCodigoAnimal(ani.getMadre());
                int codigoPadre = new AnimalDAO(this.getConDB()).getCodigoAnimal(ani.getPadre());
                /*
                 * Aka, se declara un iterator para el recorrer un array de baterias, perteneciente a una
                 * determinada camara. Luego se declara otro iterator para recorrer un array de jaulas
                 * pertenecientes a una determinada bateria.                 *
                 */
                Iterator iter = ani.getUbicacion().getBateria().iterator();
                Bateria bat = (Bateria) iter.next();
                Iterator iter2 = bat.getJaula().iterator();
                Jaula jau = (Jaula) iter2.next();
                /*
                 * Luego de obtenida la jaula y la bateria, ya que la camara ya la teniamos a trvez del animal,
                 * debemos obtener el codigo de cada una de ellas, para poder insertar el codigo de la jaula,
                 * en la tabla animal.
                 */
                int codigoTipoCamara = new TipoCamaraDAO(this.getConDB()).devolverCodigoCamara(ani.getUbicacion().getTipo_camara().getNombre());
                int codigoCamara = new CamaraDAO(this.getConDB()).getCodigoCamara(ani.getUbicacion().getNombre(), codigoTipoCamara);
                int codigoBateria = new BateriaDAO(this.getConDB()).devolverCodigoBateria(bat.getNombre(), codigoCamara);
                int codigoJaula = new JaulaDAO(this.getConDB()).devolverCodigoJaula(jau.getNombre(), codigoBateria);
                /*
                 * debemos obtener el nuevo codigo del animal, para eso utilizamos el metodo getUltimoCodigo
                 * que trae el ultimo codigo y le sumamos uno
                 */
                int codigoAnimal = this.getUltimoCodigo() + 1;
                /*
                 * en este paso realizamos un manejo de las fechas de nacimiento y de destete
                 */
                String fecha = ani.getFecha_nacimiento().toString();
                String fecha_dia = fecha.substring(8);
                String fecha_año = fecha.substring(0, 4);
                String fecha_mes = fecha.substring(5, 7);
                String fecha2 = ani.getFecha_destete_aprox().toString();
                String fecha_dia2 = fecha2.substring(8);
                String fecha_año2 = fecha2.substring(0, 4);
                String fecha_mes2 = fecha2.substring(5, 7);

                setQuery("insert into PC_ANIMAL (nombre,madre,padre,fecha_nacimiento,codigo_ubicacion,codigo_animal,fecha_destete_aproximada)"
                        + " values ( '" + ani.getNombre() + "'," + codigoMadre + "," + codigoPadre + ",'" + fecha_año + "-" + fecha_dia + "-" + fecha_mes + "',"
                        + codigoJaula + "," + codigoAnimal + ",'" + fecha_año2 + "-" + fecha_dia2 + "-" + fecha_mes2 + "');");
                setPst(getConDB().prepareStatement(getQuery()));

                ret = getPst().execute();
                getPst().close();
                return true;
            }
        } catch (SQLException ex) {
            Logger.getLogger(AnimalDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }

    /*
     * Metodo que modifica un animal, en cuanto a su sexo, ubicacion y categoria. Este metodo se debe
     * aplicar para cuando se realiza el destete del animal
     * Recibe como parametro un animal, que debe estar registrado en la base.
     * Primero se debe verificar que la jaula este libre y
     * luego se llama a un metodo de estado de jaula y la coloca como ocupada
     */
    public boolean updateDestete(Animal ani) {
        System.out.println("Actaulizar datos del animal: " + ani.datosAnimal());
        boolean band = false;
        Animal aux = null;
        //int codigoCategoria = new CategoriaDAO(this.getConDB()).devolverCodigoCategoria(ani.getCategoria().getNombre());
        /*
         * Aka, se declara un iterator para el recorrer un array de baterias, perteneciente a una
         * determinada camara. Luego se declara otro iterator para recorrer un array de jaulas
         * pertenecientes a una determinada bateria.                 *
         */
//        Iterator iter = ani.getUbicacion().getBateria().iterator();
//        Bateria bat = (Bateria) iter.next();
//        Iterator iter2 = bat.getJaula().iterator();
//        Jaula jau = (Jaula) iter2.next();


        Iterator iter_bateria = ani.getUbicacion().getBateria().iterator();
        Jaula jau = null;
        Bateria bat = null;
        System.out.println("Datos de ubicacion:\n Camara en animalDAO: " + ani.getUbicacion().getNombre());
        while (iter_bateria.hasNext()) {
            bat = (Bateria) iter_bateria.next();
            System.out.println("Bateria en animalDAO: " + bat.getNombre());
            Iterator iter_jaula = bat.getJaula().iterator();
            while (iter_jaula.hasNext()) {
                jau = (Jaula) iter_jaula.next();
                System.out.println("Jaula en animalDAO: " + jau.getNombre());
                if (jau.getEstado().getNombre().compareToIgnoreCase("LIBRE") == 0) {
                    System.out.println("El estado de la jaula:" + jau.getNombre() + " es: " + jau.getEstado().getNombre());
//                    break;
                }
            }
//            break;
        }


        /*
         * Luego de obtenida la jaula y la bateria, ya que la camara ya la teniamos a trvez del animal,
         * debemos obtener el codigo de cada una de ellas, para poder insertar el codigo de la jaula,
         * en la tabla animal.
         */
        int codigoTipoCamara = new TipoCamaraDAO(this.getConDB()).devolverCodigoCamara(ani.getUbicacion().getTipo_camara().getNombre());
        int codigoCamara = new CamaraDAO(this.getConDB()).getCodigoCamara(ani.getUbicacion().getNombre(), codigoTipoCamara);
        int codigoBateria = new BateriaDAO(this.getConDB()).devolverCodigoBateria(bat.getNombre(), codigoCamara);
        int codigoJaula = -1;// new JaulaDAO(this.getConDB()).devolverCodigoJaula(jau.getNombre(), codigoBateria);


        System.out.println("Codigo de tipo camara: " + codigoTipoCamara + " codigo de camara: " + codigoCamara + " codigo de bateria: " + codigoBateria + " codigo de jaula: " + codigoJaula);

        codigoBateria = new BateriaDAO(this.getConDB()).devolverCodigoBateria(bat.getNombre(), codigoCamara);
        codigoJaula = new JaulaDAO(this.getConDB()).devolverCodigoJaula(jau.getNombre());

        System.out.println("Segunda vuelta: codigo de tipo camara: " + codigoTipoCamara + " codigo de camara: " + codigoCamara + " codigo de bateria: " + codigoBateria + " codigo de jaula: " + codigoJaula);


        int codigoCategoria = new CategoriaDAO(this.getConDB()).devolverCodigoCategoria(ani.getCategoria().getNombre());
//        char codigoSexo=new SexoDAO(this.getConDB()).getCodigoSexo(ani.getSexo().getDescripcion());
        char codigoSexo = ani.getSexo().getNombre();

        System.out.println("Codigo de categoria: " + codigoCategoria + " codigo de sexo:" + codigoSexo);

        /*
         * debemos verificar que ese animal no exista en la base, utilizamos su nombre y su fecha de
         * nacimiento
         */
        aux = this.getAnimal(ani.getNombre(), ani.getFecha_nacimiento());


        /*
         * Ahora debemos verificar que la jaula este disponible
         */
        int codigoEstadoLibre = new EstadoJaulaDAO(this.getConDB()).devolverCodigoEstadoJaula("LIBRE");
        int codigoEstadoOcupado = new EstadoJaulaDAO(this.getConDB()).devolverCodigoEstadoJaula("OCUPADO");
        Jaula jauDisponible = new JaulaDAO(this.getConDB()).getJaulaEstado(codigoJaula, codigoEstadoLibre);
        System.out.println("Jaula encontrada: " + jauDisponible.getNombre() + " - " + jauDisponible.getEstado().getNombre());

        try {
            if (aux != null && jauDisponible != null) {
                setQuery("update PC_ANIMAL set "
                        + "codigo_categoria= " + codigoCategoria
                        + ", codigo_sexo = '" + codigoSexo + "' "
                        + ", codigo_ubicacion=" + codigoJaula
                        + " where nombre='" + ani.getNombre() + "' "
                        + " and fecha_nacimiento=to_date('" + String.valueOf(ani.getFecha_nacimiento().dateValue()) + "','yyyy/MM/DD HH:MI') ");
                System.out.println("Sentencia utilizada para el updateDestete en animalDAO: " + this.getQuery());
                setPst(getConDB().prepareStatement(getQuery()));
                getPst().executeQuery();
                getPst().close();
                band = true;
            } else {
                return false;
            }
        } catch (SQLException ex) {
            Logger.getLogger(AnimalDAO.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("Excepcion: " + ex.getMessage() + ", sentencia utilizada: " + this.getQuery());
        }
        /*
         * Si se pudo actualizar el destete del animal, actualizamos su ubicacion
         */
        if (band) {
            new JaulaDAO(this.getConDB()).updateEstadoJaula(codigoJaula, codigoEstadoOcupado);
        }
        return true;
    }

    /*
     * Metodo para devolver todos los animales de la base.
     */
    public ArrayList getAnimales() {
        ArrayList todos = null;
        todos = this.devolverAnimales("select * from PC_ANIMAL");
        return todos;
    }

    /*
     * Metodo para devolver un arrayList con todos los animales que se pueden destetar.
     * Crea la sentencia con la condicion de que la fecha_aproximada_destete >= fechaParametro.
     * Tiene parametro de entrada, la fecha a comparar y como salida un arrayList de animales
     */
    public ArrayList animalesDestetar(DATE fecha) {
        System.out.println("Tomando animales de la base que deben ser destetados...");
        ArrayList todos = null;

        String sql = "select * from pc_animal ani where fecha_destete_aproximada <= to_date('" + String.valueOf(fecha.dateValue())
                + "','yyyy/MM/DD HH:MI') and ani.codigo_animal not in "
                + "( SELECT hist.codigo_animal FROM pc_historial hist  WHERE hist.codigo_tipo_evento in "
                + "( SELECT teve.codigo_evento FROM pc_tipo_evento teve WHERE teve.nombre ='DESTETE'))";

        setQuery(sql);
        System.out.println("Sentencia que devuelve los animales a destetar: " + sql);
        todos = this.devolverAnimales(getQuery());
//        if (todos != null && todos.isEmpty() == false) {
//            System.out.println("Cantidad de animales a destetar: " + todos.size());
//        } else {
//            System.out.println("No animales por destetar");
//        }
        return todos;
    }

    /*
     * Metodo que devuelve un ArrayList con todos los animales que se pueden ralgrear.
     * Crea la sentencia con la condicion de que la fecha_aproximada_ralgro >= fechaParametro.
     * Tiene como parametro de entrada la fecha a comparar y como salida el array con los animales
     *
     * este metodo no se utiliza
     *
     */
    public ArrayList animalesRalgrear(DATE fecha) {
        ArrayList todos = null;
        String sql = "select * from pc_animal ani where fecha_ralgro_aproximada <= to_date('" + String.valueOf(fecha.dateValue())
                + " ','yyyy/MM/DD HH:MI') and ani.codigo_animal not in "
                + " ( SELECT hist.codigo_animal FROM pc_historial hist  WHERE hist.codigo_tipo_evento in "
                + " ( SELECT teve.codigo_evento FROM pc_tipo_evento teve WHERE teve.nombre ='RALGRO')) "
                + "  and ani.codigo_animal in "
                + "( SELECT hist.codigo_animal FROM pc_historial hist  WHERE hist.codigo_tipo_evento in "
                + "( SELECT teve.codigo_evento FROM pc_tipo_evento teve WHERE teve.nombre ='DESTETE'))";
        setQuery(sql);
        todos = this.devolverAnimales(getQuery());
        return todos;
    }

    /*
     * Metodo que devuelve un array con todos los animales de la base de acuerdo a la sentencia que recibe
     * como parametro.
     * retorna un arrayList de animales
     */
    private ArrayList devolverAnimales(String sentencia) {
        try {
            ArrayList todos = null;
            Animal ani = null;
            todos = new ArrayList();
            ResultSet rs;
            setQuery(
                    sentencia);
            setPst(
                    getConDB().prepareStatement(getQuery()));
            rs = getPst().executeQuery();


            while (rs.next()) {
                ani = new Animal();
                ani.setNombre(rs.getString("nombre"));
                ani.setFecha_nacimiento(new DATE(rs.getDate("fecha_nacimiento")));


                if (String.valueOf(rs.getInt("madre")) != null) {
                    ani.setMadre(this.devolverAnimalReducido(rs.getInt("madre")));


                }
                if (String.valueOf(rs.getInt("padre")) != null) {
                    ani.setPadre(this.devolverAnimalReducido(rs.getInt("padre")));


                }
                if (rs.getString("codigo_sexo") != null) {
                    ani.setSexo(new SexoDAO(this.getConDB()).getSexo(rs.getString("codigo_sexo").charAt(0)));


                }
                if(rs.getString("codigo_ubicacion")!=null){
                    /*
                 * aca debemos tener en cuenta como obtener la camara a la cual pertenece
                 * la jaula en la cual se ubica el animal. Tenemos como primer dato, el codigo de la jaula
                 * que viene desde la base, atravez de ese codigo debemos obtenerl objeto jaula,
                 * luego debemos obtener el objeto bateria (parametros codigo de bateria que esta en la jaula)
                 * y por ultimo la camara.
                 * A tener en cuenta que en cada uno de los arrays debe tener un solo objeto, para poder definir
                 * la direccion de ese animal
                 */ //declaramos un array de jaulas
                ArrayList jaulas = new ArrayList();
                //buscamos el codigo de la jaula para poder buscar el objeto jaula en la base


                int codigoJaula = rs.getInt("codigo_ubicacion");
                //buscamos en la base la jaula y la agregamos al array
                jaulas.add(new JaulaDAO(this.getConDB()).getJaula(codigoJaula));
                //buscamos el codigo de la bateria para poder bucar el objeto bateria en la base


                int codigoBateria = new JaulaDAO(this.getConDB()).devolverCodigoBateria(codigoJaula);
                //buscamos en la base la bateria de acuerdo a su codigo
                Bateria bat = new BateriaDAO(this.getConDB()).getBateria(codigoBateria);
                //le agregamos a la bateria el array de jaulas
                bat.setJaula(jaulas);
                //declaramos un array de baterias
                ArrayList baterias = new ArrayList();
                //agregamos al array de baterias, la bateria ya buscada
                baterias.add(bat);
                //buscamos el codigo de la camara a travez del codigo de la bateria que ya tenemos


                int codigoCamara = new BateriaDAO(this.getConDB()).devolverCodigoCamara(codigoBateria);
                //buscamos el objeto camara de acuerdo el codigo de camara que ya tenemos
                Camara cam = new CamaraDAO(this.getConDB()).getCamara(codigoCamara);
                //agregamos a la camara el array de baterias
                cam.setBateria(baterias);
                //agregamos al animal la camara obtenida como su ubicacion
                ani.setUbicacion(cam);
                }


                 //agregamos la categoria, si es distinto de null
                if (rs.getString("codigo_categoria") != null) {
                    ani.setCategoria(new CategoriaDAO(this.getConDB()).getCategoria(rs.getInt("codigo_categoria")));


                }

                if (rs.getDate("fecha_destete_aproximada") != null) {
                    ani.setFecha_destete_aprox(new DATE(rs.getDate("fecha_destete_aproximada")));


                }
                if (rs.getDate("fecha_peleteo_aproximada") != null) {
//                    ani.setFecha_peleteado_aprox(new DATE(rs.getDate("fecha_peleteado_aproximada")));
                    ani.setFecha_peleteado_aprox(new DATE(rs.getDate("fecha_peleteo_aproximada")));



                }
                if (rs.getDate("fecha_ralgro_aproximada") != null) {
                    ani.setFecha_ralgro_aprox(new DATE(rs.getDate("fecha_ralgro_aproximada")));


                }
                todos.add(ani);


            }
            rs.close();
            getPst().close();


            return todos;





        } catch (SQLException ex) {
            Logger.getLogger(AnimalDAO.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println(ex.getMessage());
        }
        System.out.println("Error en el metodo devolver animales (animalDao)");


        return null;


    }


    /*
     * Metodo que devuelve el ultimo animal nacido y registrado en la base.. Crea la sentencia
     * y se la envia a devolverAnimal() que retorna un objeto animal
     */
    public Animal getUltimoAnimal() {
        Animal ani = null;
        setQuery(
                "select top 1 * from PC_ANIMAL order by fecha_nacimiento desc");
        ani = this.devolverAnimal(getQuery());


        return ani;


    }

    /*
     * Metodo que devuelve un animal determinado de acuerdo al nombre pasado por parametro.
     * Este metodo crea la sentencia y se la envia al metodo devolverAnimal(), que retorna
     * un objeto animal
     *
     */
    public Animal getAnimal(String nombre, DATE fechaNacimiento) {
        String fecha = fechaNacimiento.toString();
        String fecha_dia = fecha.substring(8);
        String fecha_año = fecha.substring(0, 4);
        String fecha_mes = fecha.substring(5, 7);
//
        String sql = "SELECT * from PC_ANIMAL where nombre='" + nombre + "' and fecha_nacimiento= to_date('" + String.valueOf(fechaNacimiento.dateValue()) + "','yyyy/MM/DD HH:MI')";
        System.out.println("getAnimal en AnimalDAO: " + sql);
        setQuery(
                sql);
        Animal ani = this.devolverAnimal(getQuery());


        return ani;


    }

    /*
     * Metodo que devuelve un animal determinado de acuerdo al nombre pasado por parametro.
     * Este metodo crea la sentencia y se la envia al metodo devolverAnimal(), que retorna
     * un objeto animal
     *
     */
    public Animal getAnimal(int codigo) {
        setQuery("SELECT * from PC_ANIMAL where codigo_animal=" + codigo);
        Animal ani = this.devolverAnimal(getQuery());


        return ani;


    }

    /*
     * Metodo que devuelve un animal de acuerdo a su nombre
     */
    public Animal getAnimal(String nombre) {
        String sentencia = "SELECT * from PC_ANIMAL where nombre='" + nombre + "'";
        System.out.println("Sentencia utilizada para devolver animal por nombre: " + sentencia);
        Animal ani = this.devolverAnimal(sentencia);


        return ani;


    }

//    public Animal getAnimalRalgo(String nombre) {
//        String sql = "select * from PC_ANIMAL where nombre='" + nombre + "' ";//and fecha_peleteado is null";
//        System.out.println("Sentencia utilizada para devolver el animal que va a ser ralgreado: " + sql);
//        Animal res = this.devolverAnimal(sql);
//        return res;
//    }

    /*
     * Metodo que devuelve un animal hembra que pertenece a alguna familia
     */
    public Animal getAnimalHembra(String nombre) {
        setQuery("SELECT * from PC_ANIMAL a where a.nombre='" + nombre + "' and a.codigo_animal in "
                + "(select codigo_hembra from PC_DETALLE_FAMILIA);");
        Animal ani = this.devolverAnimal(getQuery());


        return ani;


    }

    /*
     * Metodo que devuelve un solo animal. parametro de entrada una sentencia.
     */
    private Animal devolverAnimal(String sentencia) {
        try {
            Animal ani = null;
            System.out.println("Devolviendo animal segun la sentencia...");
            ResultSet rs = null;
            setQuery(
                    sentencia);
            setPst(
                    getConDB().prepareStatement(getQuery()));
            rs = getPst().executeQuery();


            while (rs.next()) {
                System.out.println("Levantando datos de animal...");
                ani = new Animal();


                if (String.valueOf(rs.getInt("padre")) != null) {
                    System.out.println("Datos del padre:");
                    ani.setPadre(this.devolverAnimalReducido(rs.getInt("padre")));


                }
                if (String.valueOf(rs.getInt("madre")) != null) {
                    System.out.println("Datos de la madre:");
                    ani.setMadre(this.devolverAnimalReducido(rs.getInt("madre")));


                }
                ani.setNombre(rs.getString("nombre"));
                ani.setFecha_nacimiento(new DATE(rs.getDate("fecha_nacimiento")));


                if (rs.getString("codigo_sexo") != null) {
                    ani.setSexo(new SexoDAO(this.getConDB()).getSexo(rs.getString("codigo_sexo").charAt(0)));


                }

                if(rs.getString("codigo_ubicacion")!=null){
                    //declaramos un array de jaulas
                ArrayList jaulas = new ArrayList();
                //buscamos el codigo de la jaula para poder buscar el objeto jaula en la base


                int codigoJaula = rs.getInt("codigo_ubicacion");
                //buscamos en la base la jaula y la agregamos al array
                jaulas.add(new JaulaDAO(this.getConDB()).getJaula(codigoJaula));
                //buscamos el codigo de la bateria para poder bucar el objeto bateria en la base


                int codigoBateria = new JaulaDAO(this.getConDB()).devolverCodigoBateria(codigoJaula);
                //buscamos en la base la bateria de acuerdo a su codigo
                Bateria bat = new BateriaDAO(this.getConDB()).getBateria(codigoBateria);
                //le agregamos a la bateria el array de jaulas
                bat.setJaula(jaulas);
                //declaramos un array de baterias
                ArrayList baterias = new ArrayList();
                //agregamos al array de baterias, la bateria ya buscada
                baterias.add(bat);
                //buscamos el codigo de la camara a travez del codigo de la bateria que ya tenemos


                int codigoCamara = new BateriaDAO(this.getConDB()).devolverCodigoCamara(codigoBateria);
                //buscamos el objeto camara de acuerdo el codigo de camara que ya tenemos
                Camara cam = new CamaraDAO(this.getConDB()).getCamara(codigoCamara);
                //agregamos a la camara el array de baterias
                cam.setBateria(baterias);
                //agregamos al animal la camara obtenida como su ubicacion
                ani.setUbicacion(cam);
                }

                //agregamos la fecha de destete si es distinta de null


                if (rs.getDate("fecha_destete_aproximada") != null) {
                    ani.setFecha_destete_aprox(new DATE(rs.getDate("fecha_destete_aproximada")));


                } //                if (rs.getDate("fecha_peleteado") != null) {
                //                    ani.setFecha_peleteado_aprox(new DATE(rs.getDate("fecha_peleteado")));
                //                }
                if (rs.getDate("fecha_ralgro_aproximada") != null) {
                    ani.setFecha_ralgro_aprox(new DATE(rs.getDate("fecha_ralgro_aproximada")));


                } //agregamos la categoria, si es distinto de null
                if (rs.getString("codigo_categoria") != null) {
                    ani.setCategoria(new CategoriaDAO(this.getConDB()).getCategoria(rs.getInt("codigo_categoria")));


                }
            }
            getPst().close();
            rs.close();


            return ani;




        } catch (SQLException ex) {
            Logger.getLogger(AnimalDAO.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println(
                    "Excepcion: " + ex.getMessage() + ". Sentencia utilizada: " + this.getQuery());
        }


        return null;


    }
    /*
     * Metodo que devuelve un objeto animal, con solamente los atributos nombre, sexo, ubicacion
     * y fecha de nacimiento.
     * se utliza mas que nada para traer el padre y la madre de un gazapo
     * recibe como parametro el nombre del animal a buscar
     */

    private Animal devolverAnimalReducido(int codigo) {
        try {
            System.out.println("Levantando datos de padre y madre...");
            Animal ani = new Animal();
            ResultSet rs = null;
            setQuery(
                    "select nombre, codigo_sexo, codigo_ubicacion,fecha_nacimiento from PC_ANIMAL where codigo_animal=" + codigo);
            setPst(
                    getConDB().prepareStatement(getQuery()));
            rs = getPst().executeQuery();


            while (rs.next()) {
                ani.setNombre(rs.getString("nombre"));


                if (rs.getString("codigo_sexo") != null) {
                    ani.setSexo(new SexoDAO(this.getConDB()).getSexo(rs.getString("codigo_sexo").charAt(0)));


                }

                if(rs.getString("codigo_ubicacion")!=null){
                    //declaramos un array de jaulas
                ArrayList jaulas = new ArrayList();
                //buscamos el codigo de la jaula para poder buscar el objeto jaula en la base


                int codigoJaula = rs.getInt("codigo_ubicacion");
                //buscamos en la base la jaula y la agregamos al array
                jaulas.add(new JaulaDAO(this.getConDB()).getJaula(codigoJaula));
                //buscamos el codigo de la bateria para poder bucar el objeto bateria en la base


                int codigoBateria = new JaulaDAO(this.getConDB()).devolverCodigoBateria(codigoJaula);
                //buscamos en la base la bateria de acuerdo a su codigo
                Bateria bat = new BateriaDAO(this.getConDB()).getBateria(codigoBateria);
                //le agregamos a la bateria el array de jaulas
                bat.setJaula(jaulas);
                //declaramos un array de baterias
                ArrayList baterias = new ArrayList();
                //agregamos al array de baterias, la bateria ya buscada
                baterias.add(bat);
                //buscamos el codigo de la camara a travez del codigo de la bateria que ya tenemos


                int codigoCamara = new BateriaDAO(this.getConDB()).devolverCodigoCamara(codigoBateria);
                //buscamos el objeto camara de acuerdo el codigo de camara que ya tenemos
                Camara cam = new CamaraDAO(this.getConDB()).getCamara(codigoCamara);
                //agregamos a la camara el array de baterias
                cam.setBateria(baterias);
                //agregamos al animal la camara obtenida como su ubicacion
                ani.setUbicacion(cam);
                }

                ani.setFecha_nacimiento(new DATE(rs.getDate("fecha_nacimiento")));


            }
            getPst().close();
            rs.close();


            return ani;




        } catch (SQLException ex) {
            Logger.getLogger(AnimalDAO.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println(
                    "Excepcion: " + ex.getMessage() + ". Sentencia utilizada: " + this.getQuery());
        }


        return null;


    }

    /*
     * Metodo que devuelve el codigo del ultimo animal registrado en la base
     */
    public int getUltimoCodigo() {
        setQuery("select MAX(codigo_animal) AS codigo_animal from PC_ANIMAL");


        int codigo = this.devolverCodigoAnimal(getQuery());


        return codigo;



    }
    /*
     * Metodo que devuelve el codigo de un animal. Recibe por parametro al animal.
     */

    public int getCodigoAnimal(Animal ani) {
//        System.out.println(ani.getFecha_nacimiento());
//        System.out.println(ani.getNombre());
        String fecha = ani.getFecha_nacimiento().toString();
        String fecha_dia = fecha.substring(8);
        String fecha_año = fecha.substring(0, 4);
        String fecha_mes = fecha.substring(5, 7);
        String sql = "select codigo_animal from PC_ANIMAL where nombre like '%" + ani.getNombre() + "%' "
                + //                 " and fecha_nacimiento='"+ fecha_año+ "-"+fecha_dia+"-"+fecha_mes   +"'");
                " and fecha_nacimiento=to_date('" + String.valueOf(ani.getFecha_nacimiento().dateValue()) + "','yyyy/MM/DD HH:MI')";
        // int codigo = this.devolverCodigoAnimal("select codigo_animal from animal where nombre like '%NNA2%' and fecha_nacimiento='2011-01-01'");
        System.out.println("Sentencia que se usa para buscar el animal segun su nombre: " + sql);


        int codigo = this.devolverCodigoAnimal(sql);


        return codigo;


    } /*
     * Metodo que devuelve el codigo de un animal determinado, recibe como parametro una sentencia de busqueda
     */


    private int devolverCodigoAnimal(String sentencia) {
        try {
            System.out.println("Buscando el codigo del animal...");


            int codigo = -1;
            ResultSet rs = null;
//            System.out.println(sentencia);
            setPst(
                    getConDB().prepareStatement(sentencia));
//            System.out.println("paso de pedoooooooo");
            rs = getPst().executeQuery();
//            System.out.println("paso de pedoooooooo2222");


            while (rs.next()) {
//                System.out.println("paso de pedoooooooo33333");
                codigo = rs.getInt("codigo_animal");
                System.out.println("Codigo de animal encontrado: " + codigo);
//                System.out.println(String.valueOf(rs.getInt("codigo_animal")));


            }
            getPst().close();
            rs.close();


            return codigo;




        } catch (SQLException ex) {
            Logger.getLogger(AnimalDAO.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println(
                    "Excepcion: " + ex.getMessage());
        }


        return -1;


    }

    /*
     * Metodo que devuelve el padre de una familia.Recibe por parametro el nombre de la madre
     */
    public Animal devolverPadre(Animal madre) {
        Animal padre = null;
        ResultSet rs = null;
        String sentencia = null;


        int codigoMadre = this.getCodigoAnimal(madre);
        sentencia = " Select codigo_padre from PC_FAMILIA , PC_DETALLE_FAMILIA  where codigo_familia = numero_familia and codigo_hembra=" + codigoMadre;
        System.out.println("pASO DELVOLVER PADRE");
        System.out.println(sentencia);
        setQuery(
                sentencia);


        try {
            setPst(getConDB().prepareStatement(getQuery()));
            rs = getPst().executeQuery();


            while (rs.next()) {
                padre = new Animal();
                System.out.println(rs.getInt("codigo_padre"));
                padre = this.getAnimal(rs.getInt("codigo_padre"));


            }
            getPst().close();
            rs.close();



        } catch (SQLException ex) {
            Logger.getLogger(AnimalDAO.class.getName()).log(Level.SEVERE, null, ex);
        }


        return padre;


    }

    /*
     * Metodo que devuelve el siguiente nombre para un nuevo animal
     */
    public String nuevoNombre() {
        return null;
//        //obtnemos el codigo del ultimo animal
//        System.out.println("nuevo nombreee");
//
//        int codigoUltimo = this.getUltimoCodigo();
//        //declaramos el nuevoNombre
//        String nuevoNombre = "";
//        //traemos de la base el ultimo animal registrado
//        Animal ani = this.getAnimal(codigoUltimo);
//        //obtenemos su nombre
//        String nombre = ani.getNombre();
//        System.out.println(nombre);
//        //obtenemos el numero del nombre
//        String numeroNombre = nombre.substring(3);
//        //obtenemos la letra del nombre
//        String letraAñoNombre = nombre.substring(2, 3);
//        System.out.println(numeroNombre);
//        System.out.println(letraAñoNombre);
//        //convertimos el numero del nombre en un entero le sumamos uno y luego lo volvemos a string
//        int numero = Integer.parseInt(numeroNombre);
//        String numeroNombreMas = String.valueOf(numero + 1);
//        //obtenemos la fecha de hoy
//        Date fecha = new Date();
//        java.sql.Date fechaHoy = new java.sql.Date(fecha.getYear(), fecha.getMonth(), fecha.getDate());
//
//        if (ani.getFecha_nacimiento().getYear() == fechaHoy.getYear()) {
//            nuevoNombre = "NN" + letraAñoNombre + numeroNombreMas;
//        } else {
//            //buscamos la letra del año actual en la base
//            letraAñoNombre = this.traerLetra(fechaHoy.getYear());
//            nuevoNombre = "NN" + letraAñoNombre + "1";
//        }
//        return nuevoNombre;


    }

    /*
     *
     * Metodo que trae un alias de acuerdo el año pasado por parametro.
     * Se implementa en este AnimalDAO..
     */
    public String traerLetra(int año) {
        String nombre = null;
        ResultSet rs = null;
        setQuery(
                "select letra from PC_AÑO_LETRA where año =" + año);


        try {
            setPst(getConDB().prepareStatement(getQuery()));
            rs = getPst().executeQuery();


            while (rs.next()) {
                nombre = rs.getString("letra");
                System.out.println(nombre);


            }
            getPst().close();
            rs.close();



        } catch (SQLException ex) {
            Logger.getLogger(AnimalDAO.class.getName()).log(Level.SEVERE, null, ex);
        }


        return nombre;


    }

    /*
     * Metodo que devuelve un ArrayList con todos los animales que se pueden peletear.
     * Crea la sentencia con la condicion de que la fecha_peleteado >= fechaParametro.
     * Tiene como parametro de entrada la fecha a comparar y como salida el array con los animales
     */
    public ArrayList animalesPeletear(DATE fecha) {
        ArrayList todos = null;
        String sql = "select * from pc_animal ani where fecha_peleteo_aproximada <= to_date('" + String.valueOf(fecha.dateValue())
                + "','yyyy/MM/DD HH:MI') and ani.codigo_animal not in "
                + "( SELECT hist.codigo_animal FROM pc_historial hist  WHERE hist.codigo_tipo_evento in "
                + "( SELECT teve.codigo_evento FROM pc_tipo_evento teve WHERE teve.nombre ='PELETEO'))"
                + " and ani.codigo_animal in "
                + "( SELECT hist.codigo_animal FROM pc_historial hist  WHERE hist.codigo_tipo_evento in "
                + "( SELECT teve.codigo_evento FROM pc_tipo_evento teve WHERE teve.nombre ='DESTETE'))";
        System.out.println("Sentencia utilizada que devuelve los animales listos a peletear: " + sql);
//        setQuery(sql);
        todos = this.devolverAnimales(sql);


        return todos;


    }

    public boolean updatePeleteo(Animal res_animal, DATE tomarFechaSistema) {
        try {
            //begintranscation.
            System.out.println("Realizando el updatePeleteo...");
            String sql = "update pc_animal set fecha_peleteado = to_date('" + String.valueOf(tomarFechaSistema.dateValue()) + "','yyyy/MM/DD HH:MI')"
                    + " where nombre='" + res_animal.getNombre() + "'";


            this.setQuery(sql);
            System.out.println("Sentencia utilizada para el updatePeleteo en animalDAO: " + this.getQuery());
            setPst(
                    getConDB().prepareStatement(getQuery()));


            int filas_afectadas = getPst().executeUpdate();
            Iterator iter_bateria = res_animal.getUbicacion().getBateria().iterator();
            Jaula jau = null;
            Bateria bat = null;
            System.out.println("Datos de ubicacion en peleteo:\n Camara en animalDAO: " + res_animal.getUbicacion().getNombre());


            while (iter_bateria.hasNext()) {
                bat = (Bateria) iter_bateria.next();
                System.out.println("Bateria en animalDAO: " + bat.getNombre());
                Iterator iter_jaula = bat.getJaula().iterator();


                while (iter_jaula.hasNext()) {
                    jau = (Jaula) iter_jaula.next();
                    System.out.println("Jaula en animalDAO: " + jau.getNombre());


                    if (jau.getEstado().getNombre().compareToIgnoreCase("LIBRE") == 0) {
                        System.out.println("El estado de la jaula:" + jau.getNombre() + " es: " + jau.getEstado().getNombre());
//                    break;


                    }
                }
//            break;
            }

            int codigoJaula = new JaulaDAO(this.getConDB()).devolverCodigoJaula(jau.getNombre());


            int codigoEstado = new EstadoJaulaDAO(this.getConDB()).devolverCodigoEstadoJaula("Libre".toUpperCase());


            boolean res_update_jaula = new JaulaDAO(this.getConDB()).updateEstadoJaula(codigoJaula, codigoEstado);
            getPst().close();


            if (filas_afectadas > 0 && res_update_jaula) {
                System.out.println("Se realizo con exito el updatePeleteo del animal y se seteo el estado de la juala en libre.");


                return true;




            }
        } catch (SQLException ex) {
            Logger.getLogger(AnimalDAO.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println(
                    "Excepcion: " + ex.getMessage() + ". Sentencia utilizada para el updatePeleteo: " + this.getQuery());
        }


        return false;


    }

    public boolean updateAsignar(Animal animal) {
        try {
            boolean res = false;


            int cod_tipoCamara = new TipoCamaraDAO(this.getConDB()).devolverCodigoCamara(animal.getUbicacion().getTipo_camara().getNombre());


            int cod_ubicacion = new CamaraDAO(this.getConDB()).getCodigoCamara(animal.getUbicacion().getNombre(), cod_tipoCamara);


            int cod_animal = new AnimalDAO(this.getConDB()).getCodigoAnimal(animal);
            String sql = "update pc_animal set codigo_ubicacion=" + cod_ubicacion + " where codigo_animal=" + cod_animal;


            this.setPst(this.getConDB().prepareStatement(sql));


            int update = this.getPst().executeUpdate();
            System.out.println("update:" + update);


            if (update > 0) {
                res = true;


            }
            this.getPst().close();


            return res;



        } catch (SQLException ex) {
            Logger.getLogger(AnimalDAO.class.getName()).log(Level.SEVERE, null, ex);
        }


        return false;

    }

    public Animal getAnimalRalgo(String nombreAnimal, DATE fecha) {
        String sql = "select * from pc_animal ani where fecha_ralgro_aproximada <= to_date('" + String.valueOf(fecha.dateValue())
                + " ','yyyy/MM/DD HH:MI') and ani.codigo_animal not in "
                + " ( SELECT hist.codigo_animal FROM pc_historial hist  WHERE hist.codigo_tipo_evento in "
                + " ( SELECT teve.codigo_evento FROM pc_tipo_evento teve WHERE teve.nombre ='RALGRO')) "
                + "  and ani.codigo_animal in "
                + "( SELECT hist.codigo_animal FROM pc_historial hist  WHERE hist.codigo_tipo_evento in "
                + "( SELECT teve.codigo_evento FROM pc_tipo_evento teve WHERE teve.nombre ='DESTETE')) and  nombre='" + nombreAnimal + "' ";
//        String sqlRalgro = "select * from PC_ANIMAL where nombre='" + nombreAnimal + "' ";//and fecha_peleteado is null";
        System.out.println("Sentencia utilizada para devolver el animal que va a ser ralgreado: " + sql);
        Animal res = this.devolverAnimal(sql);
        return res;
    }
}
//    public ArrayList getAnimales(Sexo res_sexo, TipoEvento e_ralgro, TipoEvento e_asignado_familia) {
//        ArrayList todos = null;
//        String sql = "select * from PC_ANIMAL where codigo_sexo='" + res_sexo.getNombre() + "'";
//        todos = this.devolverAnimales(sql);
//        return todos;
//    }
        /*
 * Metodos de pruebas, para otra base de datos... no prestar atencion!!!!
 */
//    public Animal2 getAnimal2(String nombre) {
//        setQuery("SELECT * from Animal2 where nombre='" + nombre + "'");
//        Animal2 ani = this.devolverAnimal2(getQuery());
//        return ani;
//    }
//
//    private Animal2 devolverAnimal2(String sentencia) {
//        Animal2 ani = new Animal2();
//        ResultSet rs = null;
//        setQuery(sentencia);
//        try {
//            setPst(getConDB().prepareStatement(getQuery()));
//            rs = getPst().executeQuery();
//            while (rs.next()) {
//
//
//                ani.setNombre(rs.getString("nombre"));
//                ani.setFecha_nacimiento(rs.getDate("fecha_nac"));
//                ani.setMadre(rs.getString("madre"));
//                ani.setPadre(rs.getString("padre"));
//                ani.setUbicacion(rs.getString("ubicacion"));
//                return ani;
//            }
//            getPst().close();
//            rs.close();
//        } catch (SQLException ex) {
//            Logger.getLogger(AnimalDAO.class.getName()).log(Level.SEVERE, null, ex);
//        }
//        return ani;
//    }
//    public ArrayList getAnimales(Sexo res_sexo, TipoEvento e_ralgro, TipoEvento e_asignado_familia) {
//        ArrayList todos = null;
//        String sql = "select * from PC_ANIMAL where codigo_sexo='" + res_sexo.getNombre() + "'";
//        todos = this.devolverAnimales(sql);
//        return todos;
//    }
    /*
 * Metodos de pruebas, para otra base de datos... no prestar atencion!!!!
 */
//    public Animal2 getAnimal2(String nombre) {
//        setQuery("SELECT * from Animal2 where nombre='" + nombre + "'");
//        Animal2 ani = this.devolverAnimal2(getQuery());
//        return ani;
//    }
//
//    private Animal2 devolverAnimal2(String sentencia) {
//        Animal2 ani = new Animal2();
//        ResultSet rs = null;
//        setQuery(sentencia);
//        try {
//            setPst(getConDB().prepareStatement(getQuery()));
//            rs = getPst().executeQuery();
//            while (rs.next()) {
//
//
//                ani.setNombre(rs.getString("nombre"));
//                ani.setFecha_nacimiento(rs.getDate("fecha_nac"));
//                ani.setMadre(rs.getString("madre"));
//                ani.setPadre(rs.getString("padre"));
//                ani.setUbicacion(rs.getString("ubicacion"));
//                return ani;
//            }
//            getPst().close();
//            rs.close();
//        } catch (SQLException ex) {
//            Logger.getLogger(AnimalDAO.class.getName()).log(Level.SEVERE, null, ex);
//        }
//        return ani;
//    }
//}

